package com.beyondprototype.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.stomp.*;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;

import java.lang.reflect.Type;
import java.util.concurrent.ExecutionException;

//https://docs.spring.io/spring-framework/reference/web/websocket/stomp/client.html
//https://spring.io/guides/gs/messaging-stomp-websocket

@Slf4j
@EnableScheduling
@SpringBootApplication
public class StompClientApp {

    private static final String brokerUrl = "ws://localhost:8090/websocket-demo-endpoint";

    public static void main(String... args) {
        SpringApplication.run(StompClientApp.class,args);
    }

    @Bean
    public WebSocketStompClient stompClient(){
        WebSocketClient webSocketClient = new StandardWebSocketClient();
        WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
        stompClient.setMessageConverter(new StringMessageConverter());

        return stompClient;
    }

    @Bean
    public StompSession stompSession(WebSocketStompClient stompClient) throws Exception {
        StompSessionHandler sessionHandler = new StompSessionHandlerAdapter() {
            @Override
            public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
                log.info("StompSession - afterConnected :" + connectedHeaders.entrySet());
            }

            @Override
            public Type getPayloadType(StompHeaders headers) {
                return super.getPayloadType(headers);
            }

            @Override
            public void handleFrame(StompHeaders headers, Object payload) {

            }

            @Override
            public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
                log.info("StompSession - handleException", exception);
            }

            @Override
            public void handleTransportError(StompSession session, Throwable exception) {
                log.info("StompSession - handleTransportError", exception);
            }
        };

        StompSession stompSession = stompClient.connectAsync(brokerUrl, sessionHandler).get();

        return stompSession;
    }

    @EventListener(classes = {ApplicationStartedEvent.class})
    public void subscribe(ApplicationStartedEvent event) throws ExecutionException, InterruptedException {
//        WebSocketClient webSocketClient = new StandardWebSocketClient();
//        WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
//        stompClient.setMessageConverter(new StringMessageConverter());
//
//        StompSessionHandler sessionHandler = new StompSessionHandlerAdapter() {
//            @Override
//            public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
//                log.info("StompSession - afterConnected");
//            }
//        };
//
//        StompSession stompSession = stompClient.connectAsync(brokerUrl, sessionHandler).get();

        stompSession.subscribe("/topic/greetings", new StompFrameHandler() {
            @Override
            public Type getPayloadType(StompHeaders headers) {
                return String.class;
            }

            @Override
            public void handleFrame(StompHeaders headers, Object payload) {
                log.info("Received from /topic/greetings : %s".formatted(payload.toString()));
            }
        });

//        stompSession.send("/topic/greetings"," *** Hello from StompClientApp ***");

    }

//    @Autowired StompSession stompSession;
//
//    @Scheduled(fixedRate = 3000)
//    public void greeting(){
//        stompSession.send("/topic/greetings"," *** Hello from StompClientApp ***");
//    }
}
